package com.example.shiro.demo.service;

import com.alibaba.fastjson.JSONObject;
import com.example.shiro.demo.common.SecurityConsts;
import com.example.shiro.demo.entity.Permission;
import com.example.shiro.demo.entity.Role;
import com.example.shiro.demo.entity.User;
import com.example.shiro.demo.dao.RoleRepository;
import com.example.shiro.demo.dao.UserRepository;
import java.util.Optional;

import com.example.shiro.demo.shiro.security.JwtProperties;
import com.example.shiro.demo.shiro.security.JwtToken;
import com.example.shiro.demo.shiro.security.JwtUtil;
import com.example.shiro.demo.util.JedisUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import java.util.*;

/**
 * <Description> <br>
 *
 * @author renweiping<br>
 * @version 1.0<br>
 * @taskId: <br>
 * @createDate 2019/10/14 13:15 <br>
 * @see com.example.shiro.demo <br>
 */
@Service
@Transactional
public class LoginServiceImpl implements ILoginService {

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    JwtProperties jwtProperties;

    //添加用户
    @Override
    public User addUser(Map<String, Object> map) {
        User user = new User();
        //user.setId(new Random().nextLong());
        user.setName(map.get("username").toString());
        user.setPassword(Integer.valueOf(map.get("password").toString()));
        userRepository.save(user);
        return user;
    }

    //添加角色
    @Override
    public Role addRole(Map<String, Object> map) {
        Specification<User> t =  new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate p1 = criteriaBuilder.equal(root.get("id"),1);
                return p1;
            }
        };
        Optional<User> userOp = userRepository.findOne(t);
        User user = userOp.get();
        //Long.valueOf(map.get("userId").toString())
        Role role = new Role();
        role.setRoleName(map.get("roleName").toString());
        List userList = new ArrayList();
        userList.add(user);
        role.setUsers(userList);

        List roleList = new ArrayList();

        Permission permission1 = new Permission();
        permission1.setPermission("create");
        roleList.add(role);
        permission1.setRoles(roleList);

        Permission permission2 = new Permission();
        permission2.setPermission("update");
        permission2.setRoles(roleList);

        List<Permission> permissions = new ArrayList<Permission>();
        permissions.add(permission1);
        permissions.add(permission2);
        role.setPermissions(permissions);
        roleRepository.save(role);
        return role;
    }

    //查询用户通过用户名
    @Override
    public User findByName(String name) {
        return userRepository.findByName(name);
    }

    //查询用户通过用户名
    @Override
    public User findNameAndPass(String name, Integer pass) {
        User user = new User();
        user.setName(name);
        user.setPassword(pass);
        return userRepository.findByNameAndPassword(name,pass);
    }

    @Autowired
    JedisUtils jedisUtils;

    @Override
    public JSONObject login(String user,Integer pass, HttpServletResponse response){

        JSONObject jsonObject = new JSONObject();

        if (userRepository.findByName(user)==null){
            throw new AuthenticationException();
        }

        if (userRepository.findByNameAndPassword(user,pass)==null){
            throw new IncorrectCredentialsException();
        }


        String currentTimeMillis = String.valueOf(System.currentTimeMillis());
        String tokenStr = JwtUtil.sign(user,currentTimeMillis);
        AuthenticationToken token= new JwtToken(tokenStr);
        Subject subject = SecurityUtils.getSubject();
        subject.login(token);
        jsonObject.put("token",tokenStr);

        String refreshTokenKey= SecurityConsts.PREFIX_SHIRO_REFRESH_TOKEN + user;
        jedisUtils.saveString(refreshTokenKey, currentTimeMillis, jwtProperties.getTokenExpireTime()*60);

        response.setHeader(SecurityConsts.REQUEST_AUTH_HEADER, tokenStr);
        response.setHeader("Access-Control-Expose-Headers", SecurityConsts.REQUEST_AUTH_HEADER);

        return jsonObject;
    }

}
